package org.ratingviewer.parser;

import java.text.MessageFormat;

import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.nodes.*;
import org.htmlparser.tags.*;
import org.htmlparser.util.*;

public class ParserUtils {

	private static NodeList extractChildNodes(TagNode pageTag, Class<?> nodeClass) {
		NodeList textNodes = new NodeList();
		pageTag.collectInto(textNodes, new NodeClassFilter(nodeClass));
		return textNodes;
	}

	@SuppressWarnings("unchecked")
	private static <T extends TagNode> T getFirstNodeForClass(TagNode pageTag, Class<T> tagClass)
			throws PageDataNotFoundException {
		NodeList tagNodes = extractChildNodes(pageTag, tagClass);

		T tagNode = null;
		if (tagNodes.size() > 0)
			tagNode = (T) tagNodes.elementAt(0);
		else
			throw new PageDataNotFoundException(MessageFormat.format("{1} not found in tag: {0}.",
					pageTag.toHtml(), tagClass.getSimpleName()));

		return tagNode;
	}

	public static int getInt(TagNode pageTag) throws PageDataNotFoundException {
		try {
			String maybeNumber = getText(pageTag);
			return Integer.parseInt(maybeNumber);
		} catch (PageDataNotFoundException ex) {
			throw new PageDataNotFoundException(MessageFormat.format("Number not found in tag: {0}.",
					pageTag.toHtml()));
		} catch (NumberFormatException ex) {
			throw new PageDataNotFoundException(MessageFormat.format("Invalid number format in tag: {0}.",
					pageTag.toHtml()), ex);
		}
	}

	public static String getText(TagNode pageTag) throws PageDataNotFoundException {
		NodeList textNodes = extractChildNodes(pageTag, TextNode.class);

		String text = null;
		if (textNodes.size() > 0)
			text = Translate.decode(textNodes.elementAt(0).getText()).trim();
		else
			throw new PageDataNotFoundException(MessageFormat.format("Text not found in tag: {0}.",
					pageTag.toHtml()));

		return text;
	}

	public static ImageTag getFirstImageNode(TagNode pageTag) throws PageDataNotFoundException {
		return getFirstNodeForClass(pageTag, ImageTag.class);
	}

	public static LinkTag getFirstLinkNode(TagNode pageTag) throws PageDataNotFoundException {
		return getFirstNodeForClass(pageTag, LinkTag.class);
	}
}